/**
 * Clase que genera un timeout y llama a la función pasada en callback cuando el 
 * delay en milisegundos haya pasado. A la función callback se la llama pasandole
 * el object. Esto le sirve de contexto ya que en su ejecución el this se referirá
 * al objeto principal window.
 */
function Timeout(callback, delay, object) {
    this.addCallback(callback, object);
    this.timeoutID = window.setTimeout(function(id) {
        Timeout.callbacks[id]();
        Timeout.removeCallback(id);
    }, delay, this.id);
}

/**
 * mata el timeout actual
 */
Timeout.prototype.kill = function() {
    window.clearTimeout(this.timeoutID);
    Timeout.removeCallback(this.id);
};

/**
 * Agrega un callback a al contenedor estatico de callbacks
 */
Timeout.prototype.addCallback = function (callback, object) {
    this.id = this.makeUniqueId();
    Timeout.callbacks[this.id] = function() {
        if (object != null) {
            callback(object);
        } else {
            callback();
        }
    }
};

/**
 * borra un callback del contenedor estático de callbacks
 */
Timeout.removeCallback = function (id) {
    delete Timeout.callbacks[id];
};

/**
 * Genera un id random único en el contexto de Timeout.callbaks
 */
Timeout.prototype.makeUniqueId = function() {
    var id = null;
    while(Timeout.callbacks.hasOwnProperty(id=this.makeId()));
    return id;
};

/**
 * Genera un id random
 */
Timeout.prototype.makeId = function() {
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    for( var i=0; i < 10; i++ )
        text += possible.charAt(Math.floor(Math.random() * possible.length));
    return text;
};

/**
 * objeto estático contenedor de todos los callbacks, guardados en variables de 
 * nombre random (unique id).
 */
Timeout.callbacks = {};
